package com.spring.demo.spring_boot.config;

import java.lang.reflect.Method;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;

import com.spring.demo.spring_boot.utils.FastJson2JsonRedisSerializer;

import redis.clients.jedis.JedisPoolConfig;

/**
 * 
 * @author 王辉阳
 * @date 2017年8月4日 下午5:47:09
 * @description redis配置
 */
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
	@Value("${spring.redis.first.host}")
	private String host;
	@Value("${spring.redis.first.port}")
	private int port;
	@Value("${spring.redis.first.timeout}")
	private int timeout;
	@Value("${spring.redis.first.database}")
	private int database;
	@Value("${spring.redis.first.password}")
	private String password;
	@Value("${spring.redis.first.pool.max-active}")
	private int maxActive;
	@Value("${spring.redis.first.pool.max-wait}")
	private int maxWait;
	@Value("${spring.redis.first.pool.max-idle}")
	private int maxIdle;
	@Value("${spring.redis.first.pool.min-idle}")
	private int minIdle;

	@Override
	@Bean
	public KeyGenerator keyGenerator() {
		return new KeyGenerator() {
			@Override
			public Object generate(Object target, Method method, Object... params) {
				StringBuilder sb = new StringBuilder();
				sb.append(target.getClass().getName());
				sb.append(method.getName());
				for (Object obj : params) {
					sb.append(obj.toString());
				}
				return sb.toString();
			}
		};
	}

	@SuppressWarnings("rawtypes")
	@Bean
	public CacheManager cacheManager(RedisTemplate redisTemplate) {
		RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
		// Number of seconds before expiration. Defaults to unlimited (0)
//		cacheManager.setDefaultExpiration(10); // 设置key-value超时时间
		return cacheManager;
	}

	@Bean
	public RedisTemplate<String, String> redisTemplate() {
		RedisConnectionFactory factory = redisConnectionFactory();

		StringRedisTemplate template = new StringRedisTemplate(factory);
		// 使用fastjson的序列化
		template.setValueSerializer(fastJson2JsonRedisSerializer());
		// 属性设置都ok后才实例化，否则抛出异常
		template.afterPropertiesSet();
		return template;
	}

	@Bean
	@SuppressWarnings("rawtypes")
	public RedisSerializer fastJson2JsonRedisSerializer() {
		return new FastJson2JsonRedisSerializer<Object>(Object.class);
	}

	@Bean
	public JedisConnectionFactory redisConnectionFactory() {
		JedisConnectionFactory factory = new JedisConnectionFactory();
		factory.setHostName(host);
		factory.setPort(port);
		factory.setTimeout(timeout); // 设置连接超时时间
		factory.setDatabase(database);
		factory.setPassword(password);
		// 连接池配置
		JedisPoolConfig poolConfig = new JedisPoolConfig();
		poolConfig.setMaxIdle(maxIdle);
		poolConfig.setMinIdle(minIdle);
		poolConfig.setMaxWaitMillis(maxWait);
		poolConfig.setMaxTotal(maxActive);

		factory.setPoolConfig(poolConfig);
		return factory;
	}

}